home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
363_01
/
directiv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-15
|
13KB
|
455 lines
/***********************************************************************
*
* DIRECTIV.C
* Directive Routines for 68020 Assembler
*
* Description: The functions in this file carry out the functions of
* assembler directives. All the functions share the same
* calling sequence:
*
* general_name(instruction *tablePtr, int size, char *label,
* char *op, int *errorPtr)
*
* The size argument contains the size code that was specified with the
* instruction (using the definitions in ASM.H) or 0 if no size code was
* specified. The label argument is a pointer to a string (which may be
* empty) containing the label from the line containing the directive.
* The op argument is a pointer to the first non-blank character after
* the name of the directive, i.e., the operand(s) of the directive.
* The errorPtr argument is used to return a status via the standard
* mechanism.
* Argument tablePtr is not used.
*
* Author: Paul McKee
* ECE492 North Carolina State University, 12/13/86
*
* Modified A.E.Romer 16 March 1991.
* Version 1.0
*
************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "asm.h"
extern long loc;
extern char pass2, endFlag, listFlag, noOperand;
extern char *listPtr; /* Pointer to buffer where listing line is assembled
(Used to put =XXXXXXXX in the listing for EQU's and SET's */
/***********************************************************************
*
* Function org implements the ORG directive.
*
***********************************************************************/
int org(instruction *tablePtr, int size, char *label, char *op,
int *errorPtr)
{
long newLoc;
char backRef;
if (size)
NEWERROR(*errorPtr, INV_SIZE_CODE);
if (!*op)
{
NEWERROR(*errorPtr, SYNTAX);
return NORMAL;
}
op = eval(op, &newLoc, &backRef, errorPtr);
if (*errorPtr < SEVERE && !backRef)
{
NEWERROR(*errorPtr, INV_FORWARD_REF);
}
else if (*errorPtr < ERROR)
{
if (isspace(*op) || !*op)
{
/* Check for an odd value, adjust to one higher */
if (newLoc & 1)
{
NEWERROR(*errorPtr, ODD_ADDRESS);
newLoc++;
}
loc = newLoc;
/* Define the label attached to this directive, if any */
if (*label)
create(label, loc, errorPtr);
/* Show new location counter on listing */
listLoc();
}
else
NEWERROR(*errorPtr, SYNTAX);
}
return NORMAL;
}
/***********************************************************************
*
* Function end implements the END directive.
*
***********************************************************************/
int funct_end(instruction *tablePtr, int size, char *label, char *op,
int *errorPtr)
{
if (size)
NEWERROR(*errorPtr, INV_SIZE_CODE);
endFlag = TRUE;
noOperand = TRUE;
return NORMAL;
}
/***********************************************************************
*
* Function equ implements the EQU directive.
*
***********************************************************************/
int equ(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
{
long value;
char backRef;
if (size)
NEWERROR(*errorPtr, INV_SIZE_CODE);
if (!*op)
{
NEWERROR(*errorPtr, SYNTAX);
return NORMAL;
}
op = eval(op, &value, &backRef, errorPtr);
if (*errorPtr < SEVERE && !backRef)
{
NEWERROR(*errorPtr, INV_FORWARD_REF);
}
else if (*errorPtr < ERROR)
if (isspace(*op) || !*op)
if (!*label)
{
NEWERROR(*errorPtr, LABEL_REQUIRED);
}
else
{
create(label, value, errorPtr);
if (pass2 && listFlag && *errorPtr < MINOR)
{
sprintf(listPtr, "=%08lX ", value);
listPtr += 10;
}
}
else
NEWERROR(*errorPtr, SYNTAX);
return NORMAL;
}
/***********************************************************************
*
* Function set implements the SET directive.
*
***********************************************************************/
int set(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
{
long value;
int error;
char backRef;
symbolDef *symbol;
if (size)
NEWERROR(*errorPtr, INV_SIZE_CODE);
if (!*op)
{
NEWERROR(*errorPtr, SYNTAX);
return NORMAL;
}
error = OK;
op = eval(op, &value, &backRef, errorPtr);
if (*errorPtr < SEVERE && !backRef)
NEWERROR(*errorPtr, INV_FORWARD_REF);
if (*errorPtr > ERROR)
if (isspace(*op) || !*op)
if (!*label)
{
NEWERROR(*errorPtr, LABEL_REQUIRED);
}
else
{
error = OK;
symbol = create(label, value, &error);
if (error == MULTIPLE_DEFS)
if (symbol->flags & REDEFINABLE)
symbol->value = value;
else
{
NEWERROR(*errorPtr, MULTIPLE_DEFS);
return NORMAL;
}
symbol->flags |= REDEFINABLE;
if (pass2 & listFlag)
{
sprintf(listPtr, "=%08lX ", value);
listPtr += 10;
}
}
else
NEWERROR(*errorPtr, SYNTAX);
return NORMAL;
}
/**********************************************************************
*
* Function collect parses strings for dc. Each output string
* is padded with four nulls at the end.
*
**********************************************************************/
char *collect(char *s, char *d)
{
while (*s) {
if (*s == CHAR_DELIMITER)
if (*(s+1) == CHAR_DELIMITER)
{
*d++ = *s;
s += 2;
}
else
{
*d++ = '\0';
*d++ = '\0';
*d++ = '\0';
*d++ = '\0';
return ++s;
}
else
*d++ = *s++;
}
return s;
}
/***********************************************************************
*
* Function dc implements the DC directive.
*
***********************************************************************/
int dc(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
{
long outVal;
char backRef;
char string[260], *p;
if (size == SHORT)
{
NEWERROR(*errorPtr, INV_SIZE_CODE);
size = WORD;
}
else if (!size)
size = WORD;
/* Move location counter to a word boundary and fix the listing if doing
DC.W or DC.L (but not if doing DC.B, so DC.B's can be contiguous) */
if ((size & (WORD | LONG)) && (loc & 1))
{
loc++;
listLoc();
}
/* Define the label attached to this directive, if any */
if (*label)
create(label, loc, errorPtr);
/* Check for the presence of the operand list */
if (!*op)
{
NEWERROR(*errorPtr, SYNTAX);
return NORMAL;
}
do